<!--
  边栏标签页项组件

  功能特性:
  - 基于 @atlaskit/pragmatic-drag-and-drop 的拖拽重排
  - 支持 favicon 显示和错误处理
  - 加载状态和错误状态的视觉反馈
  - 右键菜单功能
  - 与 TabItem.vue 一致的拖拽体验
  - 可配置的图标大小，适应不同使用场景
-->
<template>
  <div
    ref="tabElementRef"
    class="sidebar-tab-container ma-1"
    :class="{
      'is-dragging': dragState?.type === 'dragging',
      'has-separate-window': tab.isInSeparateWindow,
      'is-pinned': tab.sidebarConfig?.isPinned && !tab.isInSeparateWindow
    }"
    @click="sctiveTab(tab)"
    @contextmenu.prevent="handleContextMenu"
  >
    <v-list-sidebar-item
      :active="active || inSeparateWindow"
      color="rgb(var(--v-theme-on-tab-active))"
      :density="density"
      :elevation="active ? 5 : 0"
      :value="tab.id"
    >
      <!-- 图标容器，带徽章 -->
      <div class="icon-wrapper">
        <v-icon v-if="tab.icon" :icon="tab.icon" :size="iconSize" />
        <v-avatar v-else class="sidebar-tab-avatar pointer-events-none" :size="iconSize">
          <!-- 正常状态 - 显示 favicon -->
          <v-img
            v-if="tab.favicon"
            :alt="tab.title"
            cover
            :src="tab.favicon"
            :title="tab.title"
            @error="onFaviconError"
          >
            <template #placeholder>
              <div class="d-flex align-center justify-center h-100">
                <v-icon :icon="mdiLink" :size="innerIconSize" />
              </div>
            </template>
            <template #error>
              <div class="d-flex align-center justify-center h-100">
                <v-icon :icon="mdiLink" :size="innerIconSize" />
              </div>
            </template>
          </v-img>
          <!-- 默认状态 -->
          <v-icon v-else :icon="mdiLink" :size="innerIconSize" />
        </v-avatar>
      </div>
    </v-list-sidebar-item>
    <!-- 状态徽章 - 右上角 -->
    <div v-if="tab.isInSeparateWindow || tab.sidebarConfig?.isPinned" class="status-badge">
      <v-icon color="white" :icon="tab.isInSeparateWindow ? mdiExport : mdiPinOutline" :size="10" />
    </div>

    <!-- 拖拽指示器 -->
    <DropIndicator
      v-if="dropState.type === 'drag-over' && dropState.closestEdge"
      :edge="dropState.closestEdge"
      offset="-3px"
      :style="dropColor"
    />

    <!--
    拖拽预览传送门
    将预览内容传送到指定的容器中
    只在预览状态时渲染
    -->
    <Teleport v-if="dragState.type === 'preview'" :to="dragState.container">
      <v-icon v-if="tab.icon" :icon="tab.icon" :size="iconSize" />
      <img
        v-else-if="tab.favicon"
        :alt="tab.title"
        :src="tab.favicon"
        :title="tab.title"
        :width="20"
      />
    </Teleport>
  </div>
</template>

<script lang="ts" setup>
import {
  mdiClose,
  mdiDelete,
  mdiExport,
  mdiImport,
  mdiLink,
  mdiPinOutline,
  mdiRefresh
} from '@mdi/js'
import { useI18n } from 'vue-i18n'
import { useDragHandle } from '@/composables/dragAndDrop/useDragHandle'
import { useDropHandle } from '@/composables/dragAndDrop/useDropHandle'
import { showContextMenu } from '@/utils/contextMenuHelper'
import { useSidebarStore } from '@/windows/layoutBrowser/stores/sidebar'
import DropIndicator from '../common/DropIndicator.vue'

const props = withDefaults(
  defineProps<{
    tab: F2.tab.Entity | F2.tab.PersistData
    index: number
    webContentsId?: number
    density?: 'default' | 'comfortable' | 'compact'
    active?: boolean
    isRight?: boolean // 位置是左边还是右边
    noDrag?: boolean // 禁止拖拽
    iconSize?: number | string // 图标大小，默认为 24
  }>(),
  {
    iconSize: 23
  }
)
const tabElementRef = ref<HTMLElement>()
const { dragState } = useDragHandle({
  el: tabElementRef,
  noDrag: props.noDrag,
  dragType: 'sidebar-tab',
  // index就动态的，这里必须使用方法
  dragData: () => {
    return {
      id: props.tab.id,
      direction: props.isRight ? 'right' : 'left',
      index: props.index
    }
  }
})
const { dropState } = useDropHandle({
  el: tabElementRef,
  noDrag: props.noDrag,
  acceptedTypes: ['sidebar-tab', 'browser-tab'],
  allowedEdges: ['top', 'bottom'],
  onDrop(source, edge) {
    const sidebarTab = source['sidebar-tab']
    const browserTab = source['browser-tab']
    if (sidebarTab) {
      const direction = props.isRight ? 'right' : 'left'
      if (sidebarTab.direction === direction) {
        // 计算目标位置（同侧重排）
        const sourceIndex = sidebarTab.index
        const targetIndex = props.index

        let finalTargetIndex = targetIndex
        if (edge === 'bottom') {
          finalTargetIndex = targetIndex + 1
        }
        // 如果源位置在目标位置之前，需要调整目标位置
        if (sourceIndex < finalTargetIndex) {
          finalTargetIndex -= 1
        }

        // 执行边栏标签页移动操作
        if (sourceIndex !== finalTargetIndex) {
          sidebarStore.moveSidebarTab(sourceIndex, finalTargetIndex, props.isRight)
        }
      } else {
        // 跨侧边栏移动
        const targetIndex = props.index

        let finalTargetIndex = targetIndex
        if (edge === 'bottom') {
          finalTargetIndex = targetIndex + 1
        }

        sidebarStore.moveSidebarTabAcrossSides(sidebarTab.id, props.isRight, finalTargetIndex)
      }
    } else if (browserTab) {
      if (!browserTab.data?.url) {
        return
      }
      let targetIndex = props.index
      if (edge === 'bottom') {
        targetIndex += 1
      }
      sidebarStore.moveTabToSidebar(browserTab.data, props.isRight, targetIndex)
    }
  }
})

const sidebarStore = useSidebarStore()
const { t } = useI18n()

// 已经在独立窗口中打开
const inSeparateWindow = computed(() => {
  return sidebarStore.separateOpenIds.includes(props.tab.id)
})

// 计算内部图标大小，约为头像大小的 2/3
const innerIconSize = computed(() => {
  const avatarSize =
    typeof props.iconSize === 'string' ? Number.parseInt(props.iconSize) : props.iconSize
  return Math.round(avatarSize * 0.67)
})

// 拖拽指示器颜色
const dropColor = computed(() => {
  return {
    background: 'rgb(var(--v-theme-primary))'
  }
})

/**
 * 处理 favicon 加载错误
 */
function onFaviconError() {
  console.warn(`Favicon 加载失败: ${props.tab.favicon}`)
  // 更新 tab 的 favicon 为 null，强制显示默认图标
}

function toggleSeparateWindow(webContentsId: number) {
  _pre_.tab.toggleSeparateWindow(webContentsId)
}

/**
 * 显示右键菜单
 */
async function handleContextMenu(event: MouseEvent) {
  event.preventDefault()
  event.stopPropagation()

  await showContextMenu([
    {
      label: `${t('sidebarTab.contextMenu.refresh')} (&R)(R)`,
      icon: mdiRefresh,
      cb: () => refreshTab()
    },
    props.webContentsId
      ? {
          label: `${t(props.tab.isInSeparateWindow ? 'sidebarTab.contextMenu.backToBrowser' : 'sidebarTab.contextMenu.separateWindow')} (&R)(R)`,
          icon: props.tab.isInSeparateWindow ? mdiImport : mdiExport,
          cb: () => {
            if (props.webContentsId) toggleSeparateWindow(props.webContentsId)
          }
        }
      : void 0,
    {
      label: `${t('sidebarTab.contextMenu.close')} (&W)(W)`,
      icon: mdiClose,
      cb: () => closeTab(),
      visible: !!sidebarStore.getTabById(props.tab.id)?.tab.data
    },
    {
      label: `${t('sidebarTab.contextMenu.removeFromSidebar')} (&D)(D)`,
      icon: mdiDelete,
      cb: () => removeFromSidebar()
    }
  ])
}

/**
 * 刷新标签页
 */
function refreshTab() {
  if (props.webContentsId) {
    _pre_.tab.refresh(props.webContentsId)
  }
}

/**
 * 关闭标签页
 */
function closeTab() {
  if (props.webContentsId) {
    _pre_.tab.close(props.webContentsId)
  }
}

/**
 * 从边栏中删除标签页
 */
async function removeFromSidebar() {
  try {
    if (props.isRight) {
      sidebarStore.removeRightTab(props.tab.id)
    } else {
      await sidebarStore.removeLeftTab(props.tab.id)
    }
    console.log('已从边栏删除标签页:', props.tab.id)
  } catch (error) {
    console.error('删除边栏标签页失败:', error)
  }
}

function sctiveTab(tab: F2.tab.Entity | F2.tab.PersistData) {
  sidebarStore.setActiveTab(tab.id, props.isRight ? 'right' : 'left')
}
</script>

<style scoped>
/* 拖拽容器样式 */
.sidebar-tab-container {
  position: relative;
}

/* 图标包装器 - 用于定位徽章 */
.icon-wrapper {
  position: relative;
  display: inline-block;
  line-height: 0;
}

/* 状态徽章 - 右上角小圆点 */
.status-badge {
  position: absolute;
  top: -1px;
  right: -1px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: linear-gradient(
    135deg,
    rgb(var(--v-theme-primary)) 0%,
    rgb(var(--v-theme-secondary)) 100%
  );
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid rgb(var(--v-theme-surface));
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  z-index: 1;
}

/* 独立窗口状态 - 使用绿色 */
.sidebar-tab-container.has-separate-window .status-badge {
  background: linear-gradient(135deg, #4caf50 0%, #66bb6a 100%);
}

/* 固定标签状态 - 使用主题色 */
.sidebar-tab-container.is-pinned .status-badge {
  background: linear-gradient(
    135deg,
    rgb(var(--v-theme-primary)) 0%,
    rgb(var(--v-theme-secondary)) 100%
  );
}

/* 边栏标签页头像样式 */
.sidebar-tab-avatar {
  background-color: rgba(var(--v-theme-surface-variant), 0.1);
  border: 1px solid rgba(var(--v-theme-outline), 0.2);
  transition: all 0.2s ease-in-out;
}

/* 头像内的图标样式 */
.sidebar-tab-avatar .v-icon {
  color: rgba(var(--v-theme-on-surface), 0.6);
}

/* 头像内的图片样式 */
.sidebar-tab-avatar .v-img {
  border-radius: inherit;
}

/* 拖拽状态样式 */
.is-dragging {
  opacity: 0.5;
  transform: scale(0.95);
  transition: all 0.2s ease;
}

/* 悬停效果 - 让徽章更明显 */
.sidebar-tab-container:hover .status-badge {
  transform: scale(1.15);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}
</style>

<i18n>
{
  "zhHans": {
    "sidebarTab": {
      "contextMenu": {
        "refresh": "刷新标签页",
        "close": "关闭标签页",
        "removeFromSidebar": "从边栏中删除",
        "separateWindow": "分离窗体",
        "backToBrowser": "回到浏览器"
      }
    }
  },
  "en": {
    "sidebarTab": {
      "contextMenu": {
        "refresh": "Refresh Tab",
        "close": "Close Tab",
        "removeFromSidebar": "Remove from Sidebar",
        "separateWindow": "Separate Window",
        "backToBrowser": "Back to Browser"
      }
    }
  }
}
</i18n>
